package com.woniu.car.filter;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.woniu.car.util.JWTUtil;
import com.woniu.car.util.ResponseEntity;

import com.woniu.car.feign.AccountFeign;
import com.woniu.car.param.ShopParam;
import com.woniu.car.util.Code;
import lombok.SneakyThrows;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.boot.configurationprocessor.json.JSONObject;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.RequestPath;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import javax.annotation.Resource;
import javax.security.auth.login.AccountException;


import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component

public class MyGlobalFilter implements GlobalFilter {
    @Resource
    private AccountFeign accountFeign;
    @SneakyThrows
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //获得请求链接
        String url = exchange.getRequest().getURI().toString();
        System.out.println("url:"+url);
        //包含登陆和注册请求放行
        String userRegister = "account/tUserAccount/register";
        String userLoginByPwd = "account/tUserAccount/loginByPwd";
        String userLoginByCode = "account/tUserAccount/loginByCode";
        String sendCode = "account/tUserAccount/sendCode";
        String shopLoginByCode = "account/tShopAccount/loginByCode";
        String backstageRegister = "account/tBackstageAccount/register";
        String backstageLogin = "account/tBackstageAccount/login";
        String superRegister = "account/tBackstageAccount/registerSuperAccount";
        String userquery = "account/tUserAccount/queryUserById";
        String shopInfoAdd = "shop/tShop/baseInfoCommit";
        String swaggerAccount = "account/v2/api-docs";
        String swaggerPlatform = "platform/v2/api-docs";
        String swaggerUser = "user/v2/api-docs";
        String swaggerGoods = "service/v2/api-docs";
        String swaggerService = "goods/v2/api-docs";
        String swaggerelastic = "elastic/v2/api-docs";
        String swaggereshop = "shop/v2/api-docs";
        String elasticServerSearch = "elastic/ElasticServerSearch";
        String elasticShopSearch = "/elastic/ElasticShopSearch";
        String elasticServerSearchById = "/elastic/ElasticServerSearchById";
        if (url.contains(userRegister) || url.contains(userLoginByPwd) || url.contains(userLoginByCode)
                || url.contains(sendCode) || url.contains(shopLoginByCode)|| url.contains(userquery)
                || url.contains(backstageRegister) || url.contains(backstageLogin)|| url.contains(shopInfoAdd)
                || url.contains(superRegister)|| url.contains(elasticServerSearch)|| url.contains(elasticShopSearch)
                || url.contains(elasticServerSearchById)
                || url.endsWith(swaggerPlatform)|| url.endsWith(swaggerAccount)
                || url.endsWith(swaggerGoods)|| url.endsWith(swaggerUser)
                || url.endsWith(swaggerService)|| url.endsWith(swaggerelastic)
                || url.endsWith(swaggereshop)) {
            System.out.println("放行");
            return chain.filter(exchange);
        } else {
            List<String> s = exchange.getRequest().getHeaders().get("token");
            //含有token且合法放行
            //进行权限校验
            if (null == s || null == s.get(0)) {
                return errorInfo(exchange,"无权限",Code.ERROR);
            } else {
                String token = s.get(0);
                //判断是谁的token
                String userId = JWTUtil.getUserId(token);
                String backId = JWTUtil.getBackId(token);
                String shopAccountId = JWTUtil.getShopAccountId(token);
                if (null != userId) {
                    //用户
                    return chain.filter(exchange);
                }
                if (null != shopAccountId) {
                    //商铺
                    return chain.filter(exchange);
                }
                if (null != backId) {
                    //后台
                    Integer bId = Integer.parseInt(backId);
                    ShopParam shopParam = new ShopParam();
                    RequestPath path = exchange.getRequest().getPath();
                    String s2 = path.toString();
                    shopParam.setUri(s2);
                    shopParam.setUserId(bId);
                    //调用服务进行校验
                    ResponseEntity responseEntity = accountFeign.queryRolePermission(shopParam);
                    Integer code = responseEntity.getCode();
                    if (code.equals(Code.ERROR)) {
                        return errorInfo(exchange,"无权限",Code.ERROR);
                    }else {
                        return chain.filter(exchange);
                    }
                }
                return errorInfo(exchange,"无权限",Code.ERROR);
            }
        }
    }


    public static Mono<Void> errorInfo(ServerWebExchange exchange, String message, Integer status) {
        // 自定义返回格式
        Map<String, Object> resultMap = new HashMap<>(8);
        resultMap.put("status", status == null ? 2 : status);
        resultMap.put("message", StringUtils.isBlank(message) ? "服务异常！" : message);
        return Mono.defer(() -> {
            byte[] bytes;
            try {
                bytes = new ObjectMapper().writeValueAsBytes(resultMap);
            } catch (JsonProcessingException e) {
                //log.error("网关响应异常：", e);
                throw new BusinessException("信息序列化异常");
            } catch (Exception e) {
                //log.error("网关响应异常：", e);
                throw new BusinessException("写入响应异常");
            }
            ServerHttpResponse response = exchange.getResponse();
            response.getHeaders().add("Content-Type", MediaType.APPLICATION_JSON_UTF8.toString());
            DataBuffer buffer = response.bufferFactory().wrap(bytes);
            return response.writeWith(Flux.just(buffer));
        });
    }




}
